package co.fitstart.weapp.api.web.controller.coach;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.demo2do.core.entity.exception.BusinessException;
import com.demo2do.core.entity.result.HttpResult;

import co.fitstart.entity.course.round.CourseRound;
import co.fitstart.entity.course.schedule.CourseSchedule;
import co.fitstart.entity.courseware.exercise.PlannedSchedule;
import co.fitstart.entity.courseware.fitnessgroup.Courseware;
import co.fitstart.entity.courseware.fitnessgroup.FitnessGroup;
import co.fitstart.entity.principal.Principal;
import co.fitstart.entity.user.StudentTargetData;
import co.fitstart.entity.user.bwh.BwhRecord;
import co.fitstart.entity.user.inbody.InbodyRecord;
import co.fitstart.weapp.api.entity.CourseAchievement;
import co.fitstart.weapp.api.entity.FitnessGroupRequest;
import co.fitstart.weapp.api.service.BwhRecordService;
import co.fitstart.weapp.api.service.CoachService;
import co.fitstart.weapp.api.service.CourseAchievementService;
import co.fitstart.weapp.api.service.CourseRoundService;
import co.fitstart.weapp.api.service.CourseScheduleService;
import co.fitstart.weapp.api.service.CoursewareService;
import co.fitstart.weapp.api.service.InbodyRecordService;
import co.fitstart.weapp.api.service.StudentTargetService;

/**
 * 
 * @author haiyan_xiao
 *
 */
@RestController
@RequestMapping("/coach/course-rounds")
public class CourseRoundController {

    private static final Logger logger = LoggerFactory.getLogger(CourseRoundController.class);

    @Autowired
    private CoachService coachService;

    @Autowired
    private CourseRoundService courseRoundService;

    @Autowired
    private CourseScheduleService courseScheduleService;

    @Autowired
    private CoursewareService coursewareService;

    @Autowired
    private StudentTargetService studentTargetService;

    @Autowired
    private InbodyRecordService inbodyRecordService;

    @Autowired
    private BwhRecordService bwhRecordService;

    @Autowired
    private CourseAchievementService courseAchievementService;

    /**
     * 
     * @param mobile
     * @param status
     * @return
     */
//    @RequestMapping(value = "", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, params = "mobile")
//    public HttpResult list(@RequestParam("mobile") String mobile,
//                           @RequestParam(value = "status", required = false, defaultValue = "editing") String status) {
//        HttpResult httpResult = new HttpResult();
//        
//        try {
//            Principal coach = coachService.load(mobile);
//            
//            if("grouping".equals(status)) {
//                httpResult.success().message("获取数据成功")
//                                    .data("courseRounds", coursewareService.listGrouping(coach));
//            } else {
//                httpResult.success().message("获取数据成功")
//                                    .data("courseRounds", coursewareService.listCourseRound(coach, status));
//            }
//        } catch (Exception e) {
//            logger.error("#CourseRoundController# list() error", e);
//            httpResult.fail("500").message("加载数据失败");
//        }
//        
//        return httpResult;
//    }

    @RequestMapping(value = "", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, params = "mobile")
    public HttpResult listByCourseStatus(@RequestParam("mobile") String mobile,
                                         @RequestParam(value = "status", required = false, defaultValue = "ready") String status) {
        HttpResult httpResult = new HttpResult();
        
        try {
            Principal coach = coachService.load(mobile);
            
            httpResult.success().message("获取数据成功")
                                .data("courseRounds", coursewareService.listCourseRound(coach, status));
        } catch (Exception e) {
            logger.error("#CourseRoundController# list() error", e);
            httpResult.fail("500").message("加载数据失败");
        }
        
        return httpResult;
    }

    /**
     * 
     * @param mobile
     * @param courseRoundId
     * @return
     */
    @RequestMapping(value = "/{courseRoundId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, params = "mobile")
    public HttpResult view(@RequestParam("mobile") String mobile,
                           @PathVariable("courseRoundId") Long courseRoundId) {
        HttpResult httpResult = new HttpResult();
        
        try {
            Principal coach = coachService.load(mobile);
            
            CourseRound courseRound = courseRoundService.load(courseRoundId);
            
            httpResult.success().message("获取数据成功")
                                .data("courseRound", courseRound)
                                .data("experience", courseRound.getCourse().isExperience())
                                .data("isMainCoach", coach == courseRound.getCoach())
                                .data("needInbody", courseRoundService.isInbodyNeeded(courseRound))
                                .data("needBwh", courseRoundService.isBwhNeeded(courseRound));
            
            if(courseRound.getFitnessGroup() == null) {
                List<FitnessGroup> fitnessGroups = coursewareService.listFitnessGroup(courseRound);
                httpResult.data("fitnessGroups", fitnessGroups)
                          .data(coursewareService.getStudentTags(courseRound.getStudent()));
            } else {
                int plannedCourse = coursewareService.getMaxFinishedCourseCourseware(courseRound);
                
                httpResult.data("plannedCourse", plannedCourse)
                          .data("restCourse", (courseRound.getCourseType().isIndividual() ? courseRound.getCourseAmount() : courseRound.getFitnessGroup().getHours()) - plannedCourse);
            }
        } catch (Exception e) {
            logger.error("#CourseRoundController# view() error", e);
            httpResult.fail("500").message("加载数据失败");
        }
        
        return httpResult;
    }

    /**
     * 
     * @param mobile
     * @param courseRoundId
     * @return
     */
    @RequestMapping(value = "/{courseRoundId}/schedules", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, params = "mobile")
    public HttpResult listSchedule(@RequestParam("mobile") String mobile,
                                   @PathVariable("courseRoundId") Long courseRoundId) {
        HttpResult httpResult = new HttpResult();
        
        try {
            CourseRound courseRound = courseRoundService.load(courseRoundId);
            
            httpResult.success().message("获取数据成功")
                                .data("schedules", courseRoundService.listCourseSchedule(courseRound));
        } catch (Exception e) {
            logger.error("#CourseRoundController# view() error", e);
            httpResult.fail("500").message("加载数据失败");
        }
        
        return httpResult;
    }

    /**
     * 
     * @param mobile
     * @param scheduleId
     * @return
     */
    @RequestMapping(value = "/{courseRoundId}/schedules/{scheduleId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, params = "mobile")
    public HttpResult viewSchedule(@RequestParam("mobile") String mobile,
                                   @PathVariable("scheduleId") Long scheduleId) {
        HttpResult httpResult = new HttpResult();
        
        try {
            Principal coach = coachService.load(mobile);
            
            CourseSchedule courseSchedule = courseScheduleService.load(scheduleId);
            
            httpResult.success().message("获取数据成功")
                                .data("schedule", courseSchedule)
                                .data("courseName", courseSchedule.getCourse().getName())
                                .data("coachAvatar", courseSchedule.getCoach().getProfile() == null ? null : courseSchedule.getCoach().getProfile().getAvatar())
                                .data("isScheduleCoach", coach == courseSchedule.getCoach());
            
            if(courseSchedule.getCourseRound().getFitnessGroup() != null && courseSchedule.getCourseRound().getCourseType().isIndividual()) {
                int session = coursewareService.getSession(courseSchedule);
                List<Courseware> coursewares = coursewareService.listCourseware(courseSchedule);
                PlannedSchedule plannedSchedule = coursewareService.getPlannedSchedule(courseSchedule.getCourseRound(), session);
                
                httpResult.data("session", session)
                          .data("coursewares", coursewares)
                          .data("plannedSchedule", plannedSchedule);
            }
        } catch (Exception e) {
            logger.error("#CourseRoundController# viewSchedule() error", e);
            httpResult.fail("500").message("加载数据失败");
        }
        
        return httpResult;
    }

    /**
     * 
     * @param mobile
     * @param courseRoundId
     * @return
     */
    @RequestMapping(value = "/{courseRoundId}/target", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, params = "mobile")
    public HttpResult target(@RequestParam("mobile") String mobile,
                             @PathVariable("courseRoundId") Long courseRoundId) {
        HttpResult httpResult = new HttpResult();
        
        try {
            CourseRound courseRound = courseRoundService.load(courseRoundId);
            
            StudentTargetData studentTargetData =studentTargetService.load(courseRound);
            
            Date effectiveStart = courseRound.getEffectiveStart() != null ? courseRound.getEffectiveStart() : new Date();
            Date effectiveEnd = courseRound.getEffectiveEnd() != null ? courseRound.getEffectiveEnd() : courseRound.calculateEffectiveEnd(effectiveStart);
            
            httpResult.success().message("获取数据成功")
                                .data("target", studentTargetData)
                                .data("studentAvatar", courseRound.getStudentAvatar())
                                .data("studentName", courseRound.getStudentName())
                                .data("startYear", DateFormatUtils.format(effectiveStart, "yyyy"))
                                .data("startDate", DateFormatUtils.format(effectiveStart, "MM月dd日"))
                                .data("endYear", DateFormatUtils.format(effectiveEnd, "yyyy"))
                                .data("endDate", DateFormatUtils.format(effectiveEnd, "MM月dd日"));
        } catch (Exception e) {
            logger.error("#CourseRoundController# target() error", e);
            httpResult.fail("500").message("加载数据失败");
        }
        
        return httpResult;
    }

    /**
     * 
     * @param mobile
     * @param courseRoundId
     * @return
     */
    @RequestMapping(value = "/{courseRoundId}/inbodys", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, params = "mobile")
    public HttpResult listInbody(@RequestParam("mobile") String mobile,
                                 @PathVariable("courseRoundId") Long courseRoundId) {
        HttpResult httpResult = new HttpResult();
        
        try {
            CourseRound courseRound = courseRoundService.load(courseRoundId);
            
            List<InbodyRecord> inbodyRecords = inbodyRecordService.list(courseRound);
            
            httpResult.success().message("获取数据成功")
                                .data("inbodys", inbodyRecords);
        } catch (Exception e) {
            logger.error("#CourseRoundController# listInbody() error", e);
            httpResult.fail("500").message("加载数据失败");
        }
        
        return httpResult;
    }

    /**
     * 
     * @param mobile
     * @param courseRoundId
     * @return
     */
    @RequestMapping(value = "/{courseRoundId}/bwhs", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, params = "mobile")
    public HttpResult listBwh(@RequestParam("mobile") String mobile,
                              @PathVariable("courseRoundId") Long courseRoundId) {
        HttpResult httpResult = new HttpResult();
        
        try {
            CourseRound courseRound = courseRoundService.load(courseRoundId);
            
            List<BwhRecord> bwhRecords = bwhRecordService.list(courseRound);
            
            httpResult.success().message("获取数据成功")
                                .data("bwhs", bwhRecords);
        } catch (Exception e) {
            logger.error("#CourseRoundController# listBwh() error", e);
            httpResult.fail("500").message("加载数据失败");
        }
        
        return httpResult;
    }

    /**
     * 
     * @param mobile
     * @param courseRoundId
     * @return
     */
    @RequestMapping(value = "/{courseRoundId}/achievement", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, params = "mobile")
    public HttpResult achievement(@RequestParam("mobile") String mobile,
                                  @PathVariable("courseRoundId") Long courseRoundId) {
        HttpResult httpResult = new HttpResult();
        
        try {
            Principal coach = coachService.load(mobile);
            CourseRound courseRound = courseRoundService.load(courseRoundId);
            CourseAchievement achievement = courseAchievementService.getCourseAchievement(courseRound);
            
            httpResult.success().message("获取数据成功")
                                .data("achievement", achievement)
                                .data("isMainCoach", coach == courseRound.getCoach())
                                .data("studentAvatar", courseRound.getStudentAvatar())
                                .data("studentName", courseRound.getStudentName());
        } catch (Exception e) {
            logger.error("#CourseRoundController# achievement() error", e);
            httpResult.fail("500").message("加载数据失败");
        }
        
        return httpResult;
    }

    /**
     * 
     * @param mobile
     * @param courseRoundId
     * @param suffix
     * @param photo
     * @return
     */
    @RequestMapping(value = "/{courseRoundId}/upload-contrast-photo", method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE, params = "mobile")
    public HttpResult uploadPhoto(@RequestParam("mobile") String mobile,
                                  @PathVariable("courseRoundId") Long courseRoundId,
                                  @RequestParam("suffix") String suffix,
                                  @RequestParam("photo") MultipartFile photo) {
        HttpResult httpResult = new HttpResult();
        
        try {
            Principal coach = coachService.load(mobile);
            CourseRound courseRound = courseRoundService.load(courseRoundId);
            
            if(coach == courseRound.getCoach()) {
                Map<String, Object> map = courseAchievementService.uploadContrastPhoto(courseRound, photo, suffix);
                
                httpResult.success().message("对比照上传成功")
                                    .data(map);
            } else {
                httpResult.fail("500").message("你不是主教练,不能上传对比照");
            }
        } catch (BusinessException e) {
            httpResult.fail("500").message(e.getMessage());
        } catch (Exception e) {
            logger.error("#CourseRoundController# uploadPhoto() uploadPhoto", e);
            httpResult.fail("500").message("操作失败");
        }
        
        return httpResult;
    }

    /**
     * 
     * @param mobile
     * @param courseRoundId
     * @return
     */
    @RequestMapping(value = "/{courseRoundId}/student-tags", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, params = "mobile")
    public HttpResult listStudentTag(@RequestParam("mobile") String mobile,
                                     @PathVariable("courseRoundId") Long courseRoundId,
                                     @RequestParam(value = "tagIds", required = false) List<Long> tagIds) {
        HttpResult httpResult = new HttpResult();
        
        try {
            httpResult.success().message("获取数据成功")
                                .data("tags", coursewareService.listStudentTags(tagIds));
        } catch (Exception e) {
            logger.error("#CourseRoundController# listStudentTag() error", e);
            httpResult.fail("500").message("加载数据失败");
        }
        
        return httpResult;
    }

    /**
     * 
     * @param mobile
     * @param courseRoundId
     * @return
     */
    @RequestMapping(value = "/{courseRoundId}/fitness-group", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, params = "mobile")
    public HttpResult editFitnessGroup(@RequestParam("mobile") String mobile,
                                       @PathVariable("courseRoundId") Long courseRoundId) {
        HttpResult httpResult = new HttpResult();
        
        try {
            CourseRound courseRound = courseRoundService.load(courseRoundId);
            List<FitnessGroup> fitnessGroups = coursewareService.listFitnessGroup(courseRound);
            
            httpResult.success().message("获取数据成功")
                                .data("originalGroup", courseRound.getFitnessGroup().getName())
                                .data("fitnessGroups", fitnessGroups);
            
        } catch (Exception e) {
            logger.error("#CourseRoundController# editFitnessGroup() error", e);
            httpResult.fail("500").message("获取数据失败");
        }
        
        return httpResult;
    }

    /**
     * 
     * @param mobile
     * @param courseRoundId
     * @param request
     * @return
     */
    @RequestMapping(value = "/{courseRoundId}/edit-fitness-group", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, params = "mobile")
    public HttpResult onEditFitnessGroup(@RequestParam("mobile") String mobile,
                                         @PathVariable("courseRoundId") Long courseRoundId,
                                         @RequestBody FitnessGroupRequest request) {
        HttpResult httpResult = new HttpResult();
        
        try {
            Principal coach = coachService.load(mobile);
            CourseRound courseRound = courseRoundService.load(courseRoundId);
            FitnessGroup fitnessGroup = coursewareService.loadFitnessGroup(request.getFitnessGroupId());
            
            if(coach == courseRound.getCoach()) {
                coursewareService.editFitnessGroup(courseRound, fitnessGroup, request.getTagIds());
                
                httpResult.success().message((courseRound.getFitnessGroup() == null ? "" : "更改") + "分组成功");
            } else {
                httpResult.fail("500").message("你不是主教练,不能" + (courseRound.getFitnessGroup() == null ? "" : "更改") + "分组");
            }
        } catch (Exception e) {
            logger.error("#CourseRoundController# onEditFitnessGroup() error", e);
            httpResult.fail("500").message("操作失败");
        }
        
        return httpResult;
    }
}
